//
//  YCAlertView.m
//  YCAlertController
//
//  Created by Yochia on 2017/1/12.
//  Copyright © 2017年 Team Brutal. All rights reserved.
//

#import "YCAlertView.h"
#import "YCAlertAction.h"

@interface YCAlertView () <UITextFieldDelegate>

@property (nonatomic, strong) UILabel *titleLabel;

@property (nonatomic, strong) UIScrollView *containerScrollView;

@property (nonatomic, strong) UIScrollView *buttonScrollView;

@property (nonatomic, strong) UITextView *messageTextView;

@property (nonatomic, strong) NSMutableArray<UIButton *> *buttons;

@property (nonatomic, strong) NSMutableArray * constraints;

@property (nonatomic, strong) NSMutableArray * containerConstraints;

@property (nonatomic) CGFloat containerHeight;

@property (nonatomic, strong) UIView * horizontalButtonSeperatorLine;

@end

@implementation YCAlertView

#pragma mark - Init

- (instancetype)init {
    if ([super init]) {        
        _alertActionsArray = [NSMutableArray array];
        _alertCustomViewsArray = [NSMutableArray array];
        _textFields = [NSMutableArray array];
        
        self.buttons = [NSMutableArray array];
        self.dismissedWhenClicked = YES;
        
        [self setupView];
    }
    return self;
}

#pragma mark - 构建视图

- (void)setupView {
    self.backgroundColor = [UIColor whiteColor];
    self.layer.masksToBounds = YES;
    self.layer.cornerRadius = 10;
    self.translatesAutoresizingMaskIntoConstraints = NO;
}

#pragma mark 标题

- (void)setTitle:(NSString *)title {
    _title = title;
    if (self.title && self.title.length > 0) {
        self.titleLabel.text = self.title;
    } else {
        [_titleLabel removeFromSuperview];
        _titleLabel = nil;
    }
    [self setNeedsUpdateConstraints];
}

- (UILabel *)titleLabel {
    if (!_titleLabel) {
        _titleLabel = [UILabel new];
        _titleLabel.backgroundColor = [UIColor colorWithWhite:0.2 alpha:1];
        _titleLabel.textColor = [UIColor colorWithWhite:0.9 alpha:1];
        _titleLabel.font = [UIFont boldSystemFontOfSize:17];
        _titleLabel.textAlignment = NSTextAlignmentCenter;
        _titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
        [self addSubview:_titleLabel];
    }
    return _titleLabel;
}

#pragma mark 内容文本

- (void)setMessage:(NSString *)message {
    _message = message;
    if (self.message && self.message.length > 0) {
        self.messageTextView.text = self.message;
    } else {
        [_messageTextView removeFromSuperview];
        _messageTextView = nil;
    }
    [self setNeedsUpdateConstraints];
}

- (UITextView *)messageTextView {
    if (!_messageTextView) {
        _messageTextView = [UITextView new];
        _messageTextView.editable = NO;
        _messageTextView.scrollEnabled = NO;
        _messageTextView.textAlignment = NSTextAlignmentCenter;
        _messageTextView.font = [UIFont systemFontOfSize:15];
        _messageTextView.translatesAutoresizingMaskIntoConstraints = NO;
        [self.containerScrollView addSubview:_messageTextView];
    }
    return _messageTextView;
}

#pragma mark 内容滚动View

- (UIScrollView *)containerScrollView {
    if (!_containerScrollView) {
        _containerScrollView = [UIScrollView new];
        _containerScrollView.delaysContentTouches = NO;
        _containerScrollView.translatesAutoresizingMaskIntoConstraints = NO;
        [self addSubview:_containerScrollView];
    }
    return _containerScrollView;
}

#pragma mark 按钮滚动View

- (UIScrollView *)buttonScrollView {
    if (!_buttonScrollView) {
        _buttonScrollView = [UIScrollView new];
        _buttonScrollView.delaysContentTouches = NO;
        _buttonScrollView.translatesAutoresizingMaskIntoConstraints = NO;
        [self addSubview:_buttonScrollView];
        
        NSArray * consts = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[buttonScrollView]|" options:0 metrics:nil views:@{@"buttonScrollView": _buttonScrollView}];
        [self addConstraints:consts];
    }
    return _containerScrollView;
}

#pragma mark Action(按钮)

- (void)addAction:(YCAlertAction *)action {
    if ([self.alertActionsArray containsObject:action]) {
        return;
    }
    
    [_alertActionsArray addObject:action];
    
    UIButton *actionButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [actionButton setTag:[_alertActionsArray indexOfObject:action]];
    [actionButton setTitle:action.title forState:UIControlStateNormal];
    if (action.style == YCAlertActionStyleDestructive) {
        [actionButton setTitleColor:[UIColor colorWithRed:0.9 green:0 blue:0 alpha:1] forState:UIControlStateNormal];
    } else {
        [actionButton setTitleColor:[UIColor colorWithWhite:0.2 alpha:1] forState:UIControlStateNormal];
    }
    [actionButton setBackgroundImage:image([UIColor colorWithWhite:0.9 alpha:1]) forState:UIControlStateNormal];
    [actionButton setBackgroundImage:image([UIColor colorWithWhite:0.8 alpha:1]) forState:UIControlStateHighlighted];
    if (action.style == YCAlertActionStyleCancel) {
        [actionButton.titleLabel setFont:[UIFont boldSystemFontOfSize:17]];
    } else {
        [actionButton.titleLabel setFont:[UIFont systemFontOfSize:16]];
    }
    [actionButton addTarget:self action:@selector(actionButtonDidClicked:) forControlEvents:UIControlEventTouchUpInside];
    actionButton.translatesAutoresizingMaskIntoConstraints = NO;
    
    UIView * line = [UIView new];
    line.backgroundColor = [UIColor colorWithWhite:1 alpha:0.8];
    line.translatesAutoresizingMaskIntoConstraints = NO;
    [actionButton addSubview:line];
    
    NSArray * consts = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[line]|" options:0 metrics:nil
                                                       views:@{@"line": line}];
    [actionButton addConstraints:consts];
    consts = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[line(1)]" options:0 metrics:nil
                                                       views:@{@"line": line}];
    [actionButton addConstraints:consts];
    
    [self addSubview:actionButton];
    
    [self.buttons addObject:actionButton];

    [self setNeedsUpdateConstraints];
}

- (void)setPreferredAction:(YCAlertAction *)preferredAction {
    for (UIButton * btn in self.buttons) {
        [btn.titleLabel setFont:[UIFont systemFontOfSize:16]];
    }
    [self.buttons[[self.alertActionsArray indexOfObject:preferredAction]].titleLabel setFont:[UIFont boldSystemFontOfSize:17]];
}

- (void)removeAction:(YCAlertAction *)action {
    if (![self.alertActionsArray containsObject:action] || !self.buttons[[self.alertActionsArray indexOfObject:action]]) {
        return;
    }
    
    [self.buttons[[self.alertActionsArray indexOfObject:action]] removeFromSuperview];
    [self.buttons removeObject:self.buttons[[self.alertActionsArray indexOfObject:action]]];
    [self setNeedsUpdateConstraints];
}

- (void)removeAllAction {
    [self.alertActionsArray removeAllObjects];
    for (UIView * view in self.buttons) {
        [view removeFromSuperview];
    }
    [self.buttons removeAllObjects];
    [self setNeedsUpdateConstraints];
}

#pragma mark 自定义View

- (void)addCustomView:(UIView *)customView {
    if (!customView) {
        return;
    }
    if ([self.alertCustomViewsArray containsObject:customView]) {
        return;
    }
    [_alertCustomViewsArray addObject:customView];
    [self.containerScrollView addSubview:customView];
    customView.translatesAutoresizingMaskIntoConstraints = NO;
    [self setNeedsUpdateConstraints];
}

- (void)addTextFieldWithConfigurationHandler:(void (^)(UITextField *))configurationHandler {
    UITextField * textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 260, 25)];
    textField.borderStyle = UITextBorderStyleRoundedRect;
    textField.delegate = self;
    textField.returnKeyType = UIReturnKeyDone;
    textField.clearButtonMode = UITextFieldViewModeWhileEditing;
    configurationHandler(textField);
    [(NSMutableArray *)_textFields addObject:textField];
    [self addCustomView:textField];
}

- (void)removeCustomView:(UIView *)customView {
    if (![self.alertCustomViewsArray containsObject:customView]) {
        return;
    }
    [self.alertCustomViewsArray removeObject:customView];
    [customView removeFromSuperview];
    [self setNeedsUpdateConstraints];
}

- (void)removeAllCustomView {
    for (UIView * view in self.alertCustomViewsArray) {
        [view removeFromSuperview];
    }
    [self.alertCustomViewsArray removeAllObjects];
    [self setNeedsUpdateConstraints];
}

#pragma mark - 更新约束

- (void)updateConstraints {
    [super updateConstraints];
    [self removeConstraints:self.constraints];
    self.constraints = [NSMutableArray array];
    
    if (_titleLabel) {
        NSArray * consts = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[title]|" options:0 metrics:nil views:@{@"title": _titleLabel}];
        [self.constraints addObjectsFromArray:consts];
        consts = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[title(40)]" options:0 metrics:nil views:@{@"title": _titleLabel}];
        [self.constraints addObjectsFromArray:consts];
    }
    
    [self.containerScrollView removeConstraints:self.containerConstraints];
    self.containerConstraints = [NSMutableArray array];
    if (_messageTextView) {
        NSArray * consts = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[message]|" options:0 metrics:nil views:@{@"message": _messageTextView}];
        [self.containerConstraints addObjectsFromArray:consts];
        
        NSLayoutConstraint * widthConstraint = [NSLayoutConstraint constraintWithItem:_messageTextView attribute:NSLayoutAttributeWidth
                                                                       relatedBy:NSLayoutRelationEqual toItem:self.containerScrollView
                                                                       attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0];
        [self.containerConstraints addObject:widthConstraint];
        
        consts = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[message]" options:0 metrics:nil views:@{@"message": _messageTextView}];
        [self.containerConstraints addObjectsFromArray:consts];
        
        NSLayoutConstraint * bottomConstraint = [NSLayoutConstraint constraintWithItem:_containerScrollView attribute:NSLayoutAttributeBottom
                                                                             relatedBy:NSLayoutRelationEqual toItem:_messageTextView
                                                                             attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0];
        bottomConstraint.priority = UILayoutPriorityDefaultLow;
        
        [self.containerConstraints addObject:bottomConstraint];
    }
    
    [self layoutCustomViews];
    [self.containerScrollView addConstraints:self.containerConstraints];
    
    if (_containerScrollView) {
        NSArray * consts = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[container]|" options:0 metrics:nil views:@{@"container": _containerScrollView}];
        [self.constraints addObjectsFromArray:consts];
        
        if (_titleLabel) {
            consts = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[title][container(height@999)]" options:0 metrics:@{@"height": @(self.containerHeight)}
                                                                                     views:@{@"title": _titleLabel, @"container": _containerScrollView}];
        } else {
            consts = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[container(height@999)]" options:0 metrics:@{@"height": @(self.containerHeight)}
                                                                                     views:@{@"container": _containerScrollView}];
        }
        [self.constraints addObjectsFromArray:consts];
        
        NSLayoutConstraint * bottomConstraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeBottom
                                                                             relatedBy:NSLayoutRelationEqual toItem:_containerScrollView
                                                                             attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0];
        bottomConstraint.priority = UILayoutPriorityDefaultLow;
        [self.constraints addObject:bottomConstraint];
    }
    
    [self.horizontalButtonSeperatorLine removeFromSuperview];
    if (self.buttons.count == 2) {
        [self layoutButtonsHorizontal];
    } else {
        [self layoutButtonsVertical];
    }
    
    [self addConstraints:self.constraints];
}


- (void)layoutCustomViews {
    NSArray * consts;
    CGFloat totalHeight = _alertCustomViewsArray.count == 0 ? 0 : 5;
    for (UIView * view in _alertCustomViewsArray) {
        CGFloat viewWidth = view.frame.size.width;
        CGFloat viewHeight = view.frame.size.height;
        NSDictionary * metrics = @{@"width": @(viewWidth), @"height": @(viewHeight)};
        
        NSLayoutConstraint * centerConstraint = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeCenterX
                                                                             relatedBy:NSLayoutRelationEqual toItem:self.containerScrollView
                                                                             attribute:NSLayoutAttributeCenterX multiplier:1.0
                                                                              constant:0.0];
        [self.containerConstraints addObject:centerConstraint];

        consts = [NSLayoutConstraint constraintsWithVisualFormat:@"H:[view(width@999)]" options:0 metrics:metrics
                                                           views:@{@"view": view}];
        [self.containerConstraints addObjectsFromArray:consts];
        NSDictionary * views = _messageTextView ? @{@"text": self.messageTextView, @"view": view} : @{@"view": view};
        NSString * vfLast = _messageTextView ? @"[text]" : @"|";
        
        if (_alertCustomViewsArray.count == 1) {
            consts = [NSLayoutConstraint constraintsWithVisualFormat:[NSString stringWithFormat:@"V:%@-5-[view(height@999)]-5-|", vfLast] options:0 metrics:metrics
                                                               views:views];
            [self.containerConstraints addObjectsFromArray:consts];
        } else if ([_alertCustomViewsArray indexOfObject:view] == 0) {
            consts = [NSLayoutConstraint constraintsWithVisualFormat:[NSString stringWithFormat:@"V:%@-5-[view(height@999)]", vfLast] options:0 metrics:metrics
                                                               views:views];
            [self.containerConstraints addObjectsFromArray:consts];
        } else if ([_alertCustomViewsArray indexOfObject:view] == _alertCustomViewsArray.count - 1) {
            UIView * last = _alertCustomViewsArray[[_alertCustomViewsArray indexOfObject:view] - 1];
            consts = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[last]-5-[view(height@999)]-5-|" options:0 metrics:metrics
                                                               views:@{@"last": last, @"view": view}];
            [self.containerConstraints addObjectsFromArray:consts];
        } else {
            UIView * last = _alertCustomViewsArray[[_alertCustomViewsArray indexOfObject:view] - 1];
            consts = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[last]-5-[view(height@999)]" options:0 metrics:metrics
                                                               views:@{@"last": last, @"view": view}];
            [self.containerConstraints addObjectsFromArray:consts];
        }
        totalHeight += 5 + viewHeight;
    }
    
    self.containerHeight = [_messageTextView sizeThatFits:CGSizeMake(280, 0)].height + totalHeight;
}

- (void)layoutButtonsHorizontal {
    UIButton * firstBtn = self.buttons[0];
    UIButton * secondBtn = self.buttons[1];
    
    self.horizontalButtonSeperatorLine = [UIView new];
    self.horizontalButtonSeperatorLine.backgroundColor = [UIColor colorWithWhite:1 alpha:0.8];
    self.horizontalButtonSeperatorLine.translatesAutoresizingMaskIntoConstraints = NO;
    [self addSubview:self.horizontalButtonSeperatorLine];
    
    NSArray * consts = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[left][line(1)][right(==left)]|" options:0 metrics:nil
                                                                 views:@{@"left": firstBtn, @"right": secondBtn, @"line": self.horizontalButtonSeperatorLine}];
    [self.constraints addObjectsFromArray:consts];
    consts = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[container][left(40)]" options:0 metrics:nil
                                                       views:@{@"container": self.containerScrollView, @"left": firstBtn}];
    [self.constraints addObjectsFromArray:consts];
    consts = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[container][line(40)]" options:0 metrics:nil
                                                       views:@{@"container": self.containerScrollView, @"line": self.horizontalButtonSeperatorLine}];
    [self.constraints addObjectsFromArray:consts];
    consts = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[container][right(40)]|" options:0 metrics:nil
                                                       views:@{@"container": self.containerScrollView, @"right": secondBtn}];
    [self.constraints addObjectsFromArray:consts];
}

- (void)layoutButtonsVertical {
    for (UIButton * button in self.buttons) {
        NSArray * consts = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[btn]|" options:0 metrics:nil
                                                                     views:@{@"btn": button}];
        [self.constraints addObjectsFromArray:consts];
        if (self.buttons.count == 1) {
            consts = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[container][btn(40)]|" options:0 metrics:nil
                                                               views:@{@"container": self.containerScrollView, @"btn": button}];
            [self.constraints addObjectsFromArray:consts];
        } else if ([self.buttons indexOfObject:button] == 0) {
            consts = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[container][btn(40)]" options:0 metrics:nil
                                                               views:@{@"container": self.containerScrollView, @"btn": button}];
            [self.constraints addObjectsFromArray:consts];
        } else if ([self.buttons indexOfObject:button] == self.buttons.count - 1) {
            UIButton * lastButton = self.buttons[[self.buttons indexOfObject:button] - 1];
            consts = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[last][btn(40)]|" options:0 metrics:nil
                                                               views:@{@"last": lastButton, @"btn": button}];
            [self.constraints addObjectsFromArray:consts];
        } else {
            UIButton * lastButton = self.buttons[[self.buttons indexOfObject:button] - 1];
            consts = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[last][btn(40)]" options:0 metrics:nil
                                                               views:@{@"last": lastButton, @"btn": button}];
            [self.constraints addObjectsFromArray:consts];
        }
    }
}

#pragma mark - 按钮Action

- (void)actionButtonDidClicked:(UIButton *)sender {
    if (self.controller && self.dismissedWhenClicked) {
        [self.controller dismissViewControllerAnimated:YES completion:^{
            void (^handler) () = self.alertActionsArray[sender.tag].handler;
            if (handler) {
                handler(self.alertActionsArray[sender.tag]);
            }
        }];
    } else {
        void (^handler) () = self.alertActionsArray[sender.tag].handler;
        if (handler) {
            handler(self.alertActionsArray[sender.tag]);
        }
    }
}

#pragma mark - 动画

- (void)popupViewAppearAnimationOrigin {
    self.transform = CGAffineTransformMakeScale(1.3, 1.3);
    self.alpha = 0;
}

- (void)popupViewAppearAnimationDestination {
    self.transform = CGAffineTransformIdentity;
    self.alpha = 1;
}

- (void)popupViewDisappearAnimationOrigin {
    self.transform = CGAffineTransformIdentity;
    self.alpha = 1;
}

- (void)popupViewDisappearAnimationDestination {
    self.transform = CGAffineTransformMakeScale(1.1, 1.1);
    self.alpha = 0;
}

#pragma mark - 默认 UITextField Delegate

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    if (![_textFields.lastObject isEqual:textField]) {
        [_textFields[[_textFields indexOfObject:textField] + 1] becomeFirstResponder];
    } else {
        [textField endEditing:YES];
    }
    return YES;
}

#pragma mark - 简易函数

UIImage * image(UIColor * color) {
    CGRect rect = CGRectMake(0, 0, 1, 1);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, color.CGColor);
    CGContextFillRect(context, rect);
    UIImage * image = UIGraphicsGetImageFromCurrentImageContext();
    return image;
}

@end
